﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.IO.Compression;
using System.Drawing;
using SharpShell.ServerRegistration;
using SharpShell.Attributes;
using SharpShell.ServiceRegistry;
using SharpShell.Registry;
using Microsoft.Win32;
using System.Windows.Forms;

namespace Tisn
{
    public class CDRFile : IDisposable
    {
        private Stream mStream;

        private static Dictionary<char, string> al = new Dictionary<char, string>();
        static CDRFile()
        {
            al.Add('8', "CorelDRAW 8");
            al.Add('A', "CorelDRAW 9");
            al.Add('B', "CorelDRAW 10");
            al.Add('C', "CorelDRAW X2");
            al.Add('D', "CorelDRAW X3");
            al.Add('E', "CorelDRAW X4");
            al.Add('F', "CorelDRAW X5");
            al.Add('G', "CorelDRAW X6");
            al.Add('H', "CorelDRAW X7");
            al.Add('J', "CorelDRAW X8");
            al.Add('K', "CorelDRAW 2017");
            al.Add('L', "CorelDRAW 2018");
        }
        public CDRFile(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            mStream = fs;
        }
        public CDRFile(Stream stream)
        {
            mStream = stream;
        }

        public Bitmap GetThumbnail(uint width)
        {
            Bitmap bitmap = null;
            try
            {
                mStream.Seek(0, SeekOrigin.Begin);
                using (BinaryReader binaryReader = new BinaryReader(mStream))
                {
                    string sig = new string(binaryReader.ReadChars(4));
                    if (sig == "RIFF")
                    {
                        var len = binaryReader.ReadUInt32();
                        binaryReader.ReadChars(4);
                        while (binaryReader.BaseStream.Position < len)
                        {
                            string fcc = new string(binaryReader.ReadChars(4));
                            int size = binaryReader.ReadInt32();
                            if (fcc == "DISP")
                            {
                                var data = binaryReader.ReadBytes(size);
                                using (var mem = new MemoryStream())
                                {
                                    using (BinaryWriter writer = new BinaryWriter(mem))
                                    {
                                        writer.Write(new char[] { 'B', 'M' });
                                        writer.Write(size + 10);
                                        writer.Write((int)0);
                                        writer.Write((int)0x36);
                                        writer.Write(data, 4, size - 4);
                                        mem.Position = 0;
                                        bitmap = new Bitmap(mem);
                                    }
                                }
                                break;
                            }
                            else
                            {
                                binaryReader.BaseStream.Position += size;
                            }
                        }
                    }
                    else
                    {
                        mStream.Seek(0, SeekOrigin.Begin);
                        try
                        {
                            using (ZipArchive zipArchive = new ZipArchive(mStream))
                            {
                                ZipArchiveEntry archiveEntry = (from za in zipArchive.Entries where (za.Name == "thumbnail.bmp" || za.Name == "thumbnail.png") select za).FirstOrDefault();
                                if (archiveEntry != null)
                                {
                                    string tmpFile = Path.GetTempPath() + Path.GetRandomFileName();
                                    archiveEntry.ExtractToFile(tmpFile, true);
                                    using (FileStream fileStream = new FileStream(tmpFile, FileMode.Open, FileAccess.Read))
                                    {
                                        bitmap = new Bitmap(fileStream);
                                        fileStream.Close();
                                    }
                                    File.Delete(tmpFile);
                                }
                            }

                        }
                        catch
                        {

                        }
                    }
                }
            }
            catch { }
            return bitmap;
        }

        public string GetVersionString()
        {
            mStream.Seek(0, SeekOrigin.Begin);
            using (BinaryReader binaryReader = new BinaryReader(mStream))
            {
                string sig = new string(binaryReader.ReadChars(4));
                string verStr = "未知文件？";
                if (sig == "RIFF")
                {
                    verStr = RiffVer(mStream);
                }
                else
                {
                    mStream.Seek(0, SeekOrigin.Begin);
                    try
                    {
                        using (ZipArchive zipArchive = new ZipArchive(mStream))
                        {
                            ZipArchiveEntry archiveEntry = (from za in zipArchive.Entries where (za.Name == "riffData.cdr" || za.Name == "root.dat") select za).FirstOrDefault();
                            if (archiveEntry != null)
                            {
                                string tmpFile = Path.GetTempPath() + Path.GetRandomFileName();
                                archiveEntry.ExtractToFile(tmpFile, true);
                                using (FileStream fileStream = new FileStream(tmpFile, FileMode.Open, FileAccess.Read))
                                {
                                    verStr = RiffVer(fileStream);
                                    fileStream.Close();
                                }
                                File.Delete(tmpFile);
                            }
                        }
                    }
                    catch
                    {

                    }
                }
                return verStr;
            }
        }

        private string RiffVer(Stream stream)
        {
            stream.Seek(0, SeekOrigin.Begin);
            using (BinaryReader binaryReader = new BinaryReader(stream))
            {
                string sig = new string(binaryReader.ReadChars(4));
                string verStr = "未知版本？";
                if (sig == "RIFF")
                {
                    binaryReader.ReadInt32();
                    string ver = new string(binaryReader.ReadChars(4));
                    if (ver.StartsWith("CDR"))
                    {
                        return char2Ver(ver[3]);
                    }
                }
                else
                {
                    throw new Exception("不是RIFF文件");
                }
                return verStr;
            }
        }

        private string char2Ver(char c)
        {
            if (al.ContainsKey(c))
            {
                return al[c];
            }
            return "未知版本？";
        }

        public void Dispose()
        {
            if (mStream != null)
            {
                mStream.Dispose();
            }
        }
    }
}
